package com.vodafone.mapreduce.divide;

import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;

import com.vodafone.mapreduce.MapReduce;

/**
 * TODO: Insert your comments here!
 */
public class DivideConfig {

    // -------------------------------------------------------------------------------------------------------------------------------------
    // Inner classes.
    // -------------------------------------------------------------------------------------------------------------------------------------

    public static enum DevideCmdlineKey {
        INPUT_FILENAME("inputFilename", "divide/access.log"), LINES_PER_ITEM("linesPerItem", "100"), OUTGOING_QUEUE_NAME(
                "outgoingQueueName",
                "com.vf.gm.vis.ps.cs.storage.mr.outgoing");

        private static final Set<String> DISPLAY_NAMES;
        static {
            DISPLAY_NAMES = new HashSet<String>();
            DevideCmdlineKey[] values = DevideCmdlineKey.values();
            for (DevideCmdlineKey cmdlineKey : values) {
                DISPLAY_NAMES.add(cmdlineKey.displayName);
            }
        }

        public static Set<String> getDisplayNames() {
            return Collections.unmodifiableSet(DISPLAY_NAMES);
        }

        private final String displayName;
        private final String defaultValue;

        private DevideCmdlineKey(String displayName, String defaultValue) {
            this.displayName = displayName;
            this.defaultValue = defaultValue;
        }

        public String getDisplayName() {
            return displayName;
        }

        public String getDefaultValue() {
            return defaultValue;
        }

    }

    /**
     * DTO for the message broker configuration.
     */
    public static class ClientConfig {
        public static ClientConfig fromKeyValueCmdlineArgs(String[] config) {
            ClientConfig mc = new ClientConfig();

            if (config != null) {
                Map<String, String> parsed = new HashMap<String, String>();
                String lastKey = null;
                for (String item : config) {
                    if (lastKey == null) {
                        lastKey = item;
                    } else {
                        parsed.put(lastKey, item);
                        lastKey = null;
                    }
                }
                for (Map.Entry<String, String> entry : parsed.entrySet()) {
                    Field f = null;
                    try {
                        f = ClientConfig.class.getField(entry.getKey());
                    } catch (NoSuchFieldException ex) {
                        // No match, just go on with the next one.
                    }
                    if (f != null) {
                        try {
                            if (f.getType().equals(String.class)) {
                                f.set(mc, entry.getValue());
                            } else if (f.getType().equals(Integer.class)) {
                                f.set(mc, Integer.valueOf(entry.getValue()));
                            }
                        } catch (Exception ex) {
                            LOG.fatal("Unable to set config value '" + entry.getValue() + " on field '" + entry.getKey() + "'!", ex);
                            System.exit(-1);
                        }
                    }
                }
            }
            return mc;
        }

        public String inputFilename = DevideCmdlineKey.INPUT_FILENAME.defaultValue;
        public Integer linesPerItem = Integer.valueOf(DevideCmdlineKey.LINES_PER_ITEM.defaultValue);
        public String outgoingQueueName = DevideCmdlineKey.OUTGOING_QUEUE_NAME.defaultValue;

        public String toString() {
            return DevideCmdlineKey.INPUT_FILENAME.displayName + ":'" + inputFilename + "'," + DevideCmdlineKey.LINES_PER_ITEM.displayName
                    + ":'" + linesPerItem + "'," + DevideCmdlineKey.OUTGOING_QUEUE_NAME.displayName + ":'" + outgoingQueueName + "'";
        }

    }

    // -------------------------------------------------------------------------------------------------------------------------------------
    // Class constants.
    // -------------------------------------------------------------------------------------------------------------------------------------

    public static final Logger LOG = MapReduce.LOG;

    // -------------------------------------------------------------------------------------------------------------------------------------
    // Class methods.
    // -------------------------------------------------------------------------------------------------------------------------------------

}
